package io2.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class NioServer3 {
    static final byte[] RS = "HTTP/1.1 200 OK\r\nContent-length:13\r\n\r\nHello, World!\r\n".getBytes();
    public static void main(String[] args) throws IOException {
        // 多路复用选择器
        Selector selector = Selector.open();

        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.bind(new InetSocketAddress(8080));
        // 把服务端channel注册到selector上
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT, serverSocketChannel);
        System.out.println("服务启动，监听8080端口");
        while(true) {
            int n = selector.select();
            System.out.println("selected num -> " + n);
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            System.out.println("select keys num -> " + selectionKeys.size());
            Iterator<SelectionKey> iterator = selectionKeys.iterator();

            while(iterator.hasNext()) {
                SelectionKey selectionKey = iterator.next();
                iterator.remove();

                // 有新的连接了
                if(selectionKey.isAcceptable()) {
                    System.out.println("有新的连接了");
                    ServerSocketChannel serverSocketChannel1 = (ServerSocketChannel) selectionKey.attachment();
                    SocketChannel accept;
                    while((accept = serverSocketChannel1.accept()) != null) {
                        accept.configureBlocking(false);
                        System.out.println("新建连接：" + accept.getRemoteAddress());
                        accept.register(selector, SelectionKey.OP_READ, accept);
                    }
                } else if(selectionKey.isReadable()) {
                    System.out.println("有数据可以读取了");
                    SocketChannel socketChannel = (SocketChannel) selectionKey.attachment();
                    if(socketChannel != null && socketChannel.isConnected()) {
                        ByteBuffer buffer = ByteBuffer.allocate(1024);
                        int r = 0;
                        try {
                            r = socketChannel.read(buffer);
                        } catch (Exception e) {
                            e.printStackTrace();
                            socketChannel.close();
                            selectionKey.cancel();
                            continue;
                        }
                        // 如果没有数据，则继续下一个
                        if (r == 0) {
                            System.out.println("没有读取到数据，继续下一个");
                            continue;
                        } else if (r < 0) {
                            // 客户端已经断开连接了
                            // 关闭通道
                            System.out.println("客户端已断开，关闭通道");
                            socketChannel.close();
                            selectionKey.cancel();
                            continue;
                        }
                        // 有数据就打印出来
                        buffer.flip();
                        byte[] bytes = new byte[buffer.remaining()];
                        buffer.get(bytes);
                        System.out.println("收到数据：" + new String(bytes));
                        buffer.clear();
                        System.out.println("数据接收完毕， 来源于：" + socketChannel.getRemoteAddress());
                        // 返回结果
                        socketChannel.write(ByteBuffer.wrap(RS));
                        System.out.println("数据发送完毕");
                    }
                }
            }
        }
    }
}
